/*!
 Temelia - Queue interface.

 Copyright (C) 2008, 2009 Ceata (http://cod.ceata.org/proiecte/temelia).

 @author Dascalu Laurentiu

 This program is free software; you can redistribute it and
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 3
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#ifndef QUEUE_H_
#define QUEUE_H_

#include "platform.h"

struct _queue_t;
typedef struct _queue_t *queue_t;

/*!
 * @brief Constructor - Allocates a queue with a given size. By default, queue won't adjust
 * the size then it's full, in order to do this the capacityIncrement to 1.
 * Complexity O(1)
 *
 * @param Queue size
 */
DECLSPEC queue_t queue_new(int size);

/*!
 * @brief Destructor - Frees memory occupied by queue.
 * Complexity O(n)
 *
 * @param Queue
 */
DECLSPEC void queue_delete(queue_t queue);

/*!
 * @brief Returns the keys number of queue.
 * Complexity O(1)
 *
 * @param Queue
 */
DECLSPEC int queue_get_size(queue_t queue);

/*!
 * @brief Returns the capacity ( maximum size ) of queue.
 * Complexity O(1)
 *
 * @param Queue
 */
DECLSPEC int queue_get_capacity(queue_t queue);

/*!
 * @brief Returns the capacity increment value; depending on it
 * the queue can increase it's size, by inserting keys, or not.
 * Complexity O(1)
 *
 * @param Queue
 */
DECLSPEC int queue_get_capacity_increment(queue_t queue);

/*!
 * @brief Sets increase variable in order to allow the insertions function to
 * reallocate when queue becomes full.
 * Complexity O(1)
 *
 * @param Queue
 * @param 1 if the size increasing operation is allowed and 0 otherwise
 */
DECLSPEC void queue_set_capacity_increment(queue_t queue, int new_increase);

/*!
 * @brief Returns 1 if the queue is empty and 0 if it isn't.
 * Complexity O(1)
 *
 * @param Queue
 */
DECLSPEC int queue_is_empty(queue_t queue);

/*!
 * @brief Returns 1 if the queue is full and 0 if it ins't.
 * Complexity O(1)
 *
 * @param Queue
 */
DECLSPEC int queue_is_full(queue_t queue);

/*!
 * @brief Inserts an key to front of queue.
 * Complexity O(1)
 *
 * @param Queue
 * @param Key
 */
DECLSPEC void queue_push_front(queue_t queue, void *key);

/*!
 * @brief Inserts an key to the end of queue.
 * Complexity O(1)
 *
 * @param Queue
 * @param Key
 */
DECLSPEC void queue_push_back(queue_t queue, void *key);

/*!
 * @brief Returns the reference to the first node of the queue;
 * you should cast this pointer to doubly_linked_list_iterator_t.
 * Complexity O(1)
 *
 * @param Queue
 */
DECLSPEC void *queue_get_begin(queue_t queue);

/*!
 * @brief Returns the reference to the last node of the queue;
 * you should cast this pointer to doubly_linked_list_iterator_t
 * Complexity O(1)
 *
 * @param Queue
 */
DECLSPEC void *queue_get_end();

/*!
 * @brief Sets a new first node for queue.
 * Complexity O(1)
 *
 * @param Queue
 */
DECLSPEC void queue_set_begin(queue_t queue, void *begin);

/*!
 * @brief Sets a new last node for queue.
 * Complexity O(1)
 *
 * @param Queue
 */
DECLSPEC void queue_set_end(queue_t queue, void *end);

/*!
 * @brief Returns the key from the peek of queue.
 * Complexity O(1)
 *
 * @param Queue
 */
DECLSPEC void *queue_get_front(queue_t queue);

/*!
 * @brief Returns the key from the end of queue.
 * Complexity O(1)
 *
 * @param Queue
 */
DECLSPEC void *queue_get_back(queue_t queue);

/*!
 * @brief Removes the front key.
 * Complexity O(1)
 *
 * @param Queue
 */
DECLSPEC void queue_pop_front(queue_t queue);

/*!
 * @brief Removes the key from the end of the queue.
 * Complexity O(1)
 *
 * @param Queue
 */
DECLSPEC void queue_pop_back(queue_t queue);

/*!
 * @brief Lists the keys from the queue in the given order. If order=1 the functions
 * prints the keys in the natural order (FIFO) and if order=-1 it prints the
 * keys in the reverse natural order.
 * Complexity O(n)
 *
 * @param Queue
 * @param Pointer to iterating function
 * @param Pointer to context
 * @param Printing order
 */
DECLSPEC void queue_iterate(queue_t queue, void key_handler(void *key, void *context),
		void *context, int order);

#endif /* QUEUE_H_ */
